#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
#include <string.h>

#define STRSIZE 100
#define NPROCESSOR 4
#define NTHREAD 4
#define BLOCK_LOW(id,p,n) (((id)*(n))/(p))
#define BLOCK_HIGH(id,p,n) (BLOCK_LOW((id)+1,(p),(n)) - 1)

void clear_str(char *,int);
int palindrome(char *);
int get_border(FILE *, int);

int main(int argc, char *argv[]) {

    int nprocess, rank;
    char aux[STRSIZE];
    char **text = (char**)malloc(sizeof(char*));
    int asc_palindrome = 0;
    int s_text = 0;
    int i = 0;
    int pa = 0;
    int global_pa;
    int boole = 0;


    MPI_Init(&argc,&argv);
    MPI_Comm_size(MPI_COMM_WORLD,&nprocess);
    MPI_Comm_rank(MPI_COMM_WORLD,&rank);

    FILE *fp;
    int begin, end, size_f;

    if ((fp = fopen("shakespe.txt","r")) == NULL) {
        printf("ERRO AO ABRIR O ARQUIVO\n");
        exit(1);
    }

    fseek(fp,0,SEEK_END);
    size_f = ftell(fp);

    if (rank != 0) {
        begin = BLOCK_LOW(rank,nprocess,size_f);
        begin = get_border(fp,begin);
    } else {
        fseek(fp,0,SEEK_SET);
    }

    end = BLOCK_HIGH(rank,nprocess,size_f);

    clear_str(aux,STRSIZE);

    while(ftell(fp) < end) {

        fscanf(fp,"%s",aux);
        text = (char**)realloc(text,sizeof(char*)*(s_text+1));
        text[i] = (char*)malloc(sizeof(char)*(strlen(aux)+1));
        strcpy(text[i],aux);
        clear_str(aux,STRSIZE);
        s_text++;
        i++;

    }

    for ( i = 0; i < s_text; i++ ) {
        asc_palindrome = palindrome(text[i]);
        if (asc_palindrome > 0) {
            pa += 1;
        }
    }

    MPI_Reduce(&pa,&global_pa,1,MPI_INT,MPI_SUM,0,MPI_COMM_WORLD);
    if ( rank == 0 ) {
        printf("%d\n",global_pa);
    }
    free(*text);
    free(text);
    fclose(fp);

    MPI_Finalize();

    return 0;
 }

int get_border(FILE *fp, int pos) {

    fseek(fp,pos,SEEK_SET);
    char c = fgetc(fp);
    int i = 0;

    while( c != ' ' && c != '\t' ) {
        c = fgetc(fp);
        i++;
    }

    return i;

}

int palindrome(char *str) {

    int i,l,j;
    int ssize = strlen(str);
    int ascii_sum = 0;

    i=0;
    j=ssize-1;
    //ignorando caracteres especiais no final de palavra, no final da palavra, exem.: (kfbrwiufh)
    for(l=j;l>=0;l--)
	if((int)str[l]<65 || ((int)str[l]>90 && (int)str[l]<97) || (int)str[l]>122 )
		j--;
	else
		break;

    //ignorando caracteres especiais no inicio de palavra, no final da palavra, exem.: (kfbrwiufh)
    for(l=0;l<=j;l++)
	if((int)str[l]<65 || ((int)str[l]>90 && (int)str[l]<97) || (int)str[l]>122 )
		i++;
	else
		break;

    //se passar aq é palimdrome
    if(j==-1)
	return 0;//isso significa e existe uma palavra com apenas simbolos especiais
    for (  ;i <= j;i++){
        if (   ((int)str[j] != (int)str[i])   &&         ((int)str[j]+32 != (int)str[i])   && ((int)str[j] != (int)str[i]+32)         )
            return 0;
        else
            ascii_sum += (i != j) ? (int)str[j] + (int)str[i] : (int)str[i];
        j--;
    }
    //printf("%s ",str);
    return ascii_sum;

}

void clear_str(char *c, int n) {

    int i = 0;

    for ( i = 0; i < n; i++ ) {
        c[i] = 0;
    }

}

